import javax.swing.*;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.lang.Math;

import java.net.InetAddress;

@SuppressWarnings("unused")
public class ServerGui extends JFrame {

	private static final long serialVersionUID = -8893383475071743725L;
	public static final int WIDTH = 800;
	public static final int HEIGHT = 600;
	public static final int MAX_CLIENTS = 40;

	Server server;
	JTextField paymentNumber;
	JPanel userStatus;
	JLabel[][] status;
	JButton nextStep, wait;
	GridBagLayout layout;
	GridBagConstraints c;
	boolean okayToSave;
	int stage = Pledge.INSTRUCTIONS;
	int chosenNumber;

	/* Parameters sent to server for communication with clients */
	boolean gain;
	int param;
	int[] params;
	int payoutParam;

	public ServerGui(Server s) {
		super();
		setSize(WIDTH, HEIGHT);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		BorderLayout bl = new BorderLayout();
		setLayout(bl);
		setVisible(true);

		okayToSave = false;
		server = s;
		String IPAddress = null;

		// 2 JLabels, JTextArea inside JScrollFrame, JTextField, 2 JButtons
		try {
			IPAddress = InetAddress.getLocalHost().getHostAddress();
		} catch (Exception e) {
			System.err.println(e);
		}
		JLabel progress = new JLabel("Progress:");
		userStatus = new JPanel();

		userStatus.setBackground(Color.white);
		userStatus.setOpaque(true);
		layout = new GridBagLayout();
		c = new GridBagConstraints();
		userStatus.setLayout(layout);
		status = new JLabel[MAX_CLIENTS + 1][2];

		for (int i = 0; i < MAX_CLIENTS + 1; i++) {
			status[i][0] = new JLabel("");
			status[i][1] = new JLabel("");
		}

		c.weightx = 1;
		c.weighty = 1;
		c.gridy = MAX_CLIENTS;
		layout.setConstraints(status[MAX_CLIENTS][0], c);
		userStatus.add(status[MAX_CLIENTS][0], c);
		layout.setConstraints(status[MAX_CLIENTS][1], c);
		userStatus.add(status[MAX_CLIENTS][1], c);

		status[MAX_CLIENTS][0].setText(" ");
		status[MAX_CLIENTS][1].setText(" ");

		JPanel header1 = new JPanel();
		JLabel header1L = new JLabel(
				"University of California San Diego, Economics Department");
		header1.add(header1L);
		header1.setBackground(new Color(100, 149, 237));
		header1.setOpaque(true);
		JPanel header2 = new JPanel();
		JLabel header2L = new JLabel("Server Monitor Program: " + IPAddress);
		header2.add(header2L);
		header2.setBackground(new Color(255, 215, 0));
		header2.setOpaque(true);

		JPanel north = new JPanel();
		north.setLayout(new BorderLayout());
		north.add(header1, BorderLayout.NORTH);
		north.add(header2, BorderLayout.CENTER);
		north.add(progress, BorderLayout.SOUTH);
		add(north, BorderLayout.NORTH);

		JScrollPane pane = new JScrollPane(userStatus);
		// userStatus.setPreferredScrollableViewportSize(new Dimension(500,
		// 375));

		add(pane, BorderLayout.CENTER);

		JPanel south = new JPanel();
		south.setOpaque(false);
		
		wait = new JButton("Wait");
		wait.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				
			}	
		});
		wait.setEnabled(false);
		south.add(wait);
		
		nextStep = new JButton("Waiting...");
		nextStep.addActionListener(new NeXTStep());
		nextStep.setEnabled(false);
		south.add(nextStep);
		add(south, BorderLayout.SOUTH);

		validate();
		repaint();
	}

	// To Add Clients to Board, or updates them
	public void updateStatus(ClientInfo[] ci, int index, int guiIndex) {
		int stat = ci[index].getStatus();
		int step = (stat / 2) + 1;

		if (stat == Pledge.INSTRUCTIONS) {
			// if new client, adds the jlabels
			c.gridx = 0;
			c.gridy = index;
			c.weightx = 1;
			c.weighty = 0;
			c.anchor = GridBagConstraints.FIRST_LINE_START;
			c.fill = GridBagConstraints.HORIZONTAL;
			layout.setConstraints(status[index][0], c);
			userStatus.add(status[index][0], c);

			c.gridx = 1;
			layout.setConstraints(status[index][1], c);
			userStatus.add(status[index][1], c);

			status[index][0].setText(ci[index].subjectNumber);
			status[index][1].setText("reading instructions");

			// alternates background color
			if (index % 2 == 1) {
				status[guiIndex][0].setBackground(new Color(236, 243, 255));
				status[guiIndex][0].setOpaque(true);
				status[guiIndex][1].setBackground(new Color(236, 243, 255));
				status[guiIndex][1].setOpaque(true);
			}

			// if working on gambles
		} else if (stat == Pledge.WAITING) {
			status[guiIndex][1].setText("waiting");
			status[guiIndex][1].repaint();
		} else if (stat == Pledge.DONE){
			status[guiIndex][1].setText("done");
			status[guiIndex][1].repaint();
		} else {
			status[guiIndex][1].setText("Step " + step
					+ (stat % 2 == 1 ? " : done" : " : working..."));
			status[guiIndex][1].repaint();
		}

		boolean next = true;

		if (stage < stat) {
			if (stat == Pledge.STAGE1_DONE) {
				nextStep.setText("Next Round");
				nextStep.setEnabled(true);
			} else if(stat == Pledge.WAITING) {
				nextStep.setText("Next Round");
				nextStep.setEnabled(true);
			} else if (Server.CurrRound == Server.maxround) {
				nextStep.setText("Last Round");
				nextStep.setEnabled(true); /*is this correct?*/
			} else if (Server.CurrRound > Server.maxround) {
				nextStep.setText("End Experiment");
				nextStep.setEnabled(true); /*is this correct?*/
			}
			else {
				nextStep.setEnabled(true);
			}
		}
		for (int i = 0; (ci[i] != null) && (i < ci.length || next); i++) {
			if (ci[i].getStatus() != stat)
				next = false;
		}
		if (next) {
			stage = stat;
		}
	}

	public class NeXTStep implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			ServerGui parent = (ServerGui) ((JComponent) e.getSource())
					.getTopLevelAncestor();
			int cont;

			switch (parent.stage) {
			case Pledge.INSTRUCTIONS:
				break;
				
			case Pledge.STAGE1_WORKING:
				cont = JOptionPane.showConfirmDialog(parent,
						"Not everyone is finished. Are you sure?", "???",
						JOptionPane.ERROR_MESSAGE);
				if (cont == JOptionPane.NO_OPTION) {
					return;
				}
				
			case Pledge.STAGE1_DONE:

				int s = -1,
				r = 0;

				//if the next round will take us over our cap, exit everyone out
//				if(Server.CurrRound + 1 > Server.maxround)
//				{
//					parent.server.closeClients();
//				}
//				do {
//					String gambleNumber = JOptionPane.showInputDialog(parent,
//							"Which set of gambles will we be using?",
//							"Chose gamble", JOptionPane.QUESTION_MESSAGE);
//
//					parent.param = Integer.parseInt(gambleNumber.trim());
//
//					if (parent.param > parent.server.allowable
//							|| parent.param < 1) {
//						JOptionPane.showMessageDialog(parent,
//								"Number outside allowable bounds",
//								"Invalid Entry", JOptionPane.ERROR_MESSAGE);
//					}
//				} while (parent.param > parent.server.allowable
//						|| parent.param < 1);

				parent.chosenNumber = param;
				parent.server.performRound(parent.server.getPledges(), Server.getA(), Server.getB(), Server.getAlpha());
				parent.server.pledges.clear();
//				parent.server.saveData(1);
								
//				String result = JOptionPane
//						.showInputDialog(
//								parent,
//								"<html>Please enter a randomly chosen number<p> between 0 and 100, inclusive, to determine payouts.</html>",
//								"Determine payouts",
//								JOptionPane.QUESTION_MESSAGE);
//				int intResult = Integer.parseInt(result.trim());
//				
//				int[] params = {parent.chosenNumber, intResult};
//				parent.params = params;
//				parent.server.sendParameters(params);
									
//				parent.server.saveData(2);						
				return;
							
			case Pledge.DONE:
				cont = JOptionPane.showConfirmDialog(parent, "Are you sure?",
						"Are You Sure?", JOptionPane.ERROR_MESSAGE);
				if (cont == JOptionPane.NO_OPTION) {
					return;
				}
				
				//parent.server.saveData(3);
				parent.server.closeClients();

			default:
				System.err.println("default: " + parent.stage);
				break;
			}
		}
	}
}